<template>
  <table-date-filter @change="onChangeDateTimeFilter" />

  <el-button
    class="bg-[var(--el-color-primary)]"
    type="primary"
    @click="exportAllLogs"
    >{{ $t('global.action.exportAll') }}</el-button
  >
  <el-button type="danger" class="bg-red-500" @click="deleteAllLogs">
    {{ $t('global.action.deleteAll') }}
  </el-button>
  <div v-if="multipleSelection.length" class="w-full h-8 flex justify-end">
    <el-button @click="BatchExportLogs">{{
      $t('global.action.batchExport')
    }}</el-button>
  </div>

  <el-table
    ref="tableRef"
    row-key="Id"
    :data="TableData"
    style="width: 100%"
    @selection-change="handleSelectionChange"
    @sort-change="sortChange"
  >
    <el-table-column type="expand">
      <template #default="props">
        <div m="4">
          <p v-for="(value, key) in props.row" :key="key" m="t-0 b-2">
            {{ key + ': ' + value }}
          </p>
        </div>
      </template>
    </el-table-column>
    <el-table-column type="selection" width="55" />
    <el-table-column prop="Id" label="ID" width="100" />
    <el-table-column
      prop="CodeType"
      :label="$t('pagePostCodeLogs.table.CodeType')"
    />
    <el-table-column
      prop="Severity"
      :label="$t('pageEventLogs.table.severity')"
      width="100"
      :filters="[
        { text: 'OK', value: 'OK' },
        { text: 'Critical', value: 'Critical' },
        { text: 'Warning', value: 'Warning' },
      ]"
      :filter-method="filterHandler"
      filter-placement="bottom-end"
    >
      <template #default="scope">
        <el-tag :type="tagType(scope.row.Severity)" disable-transitions>{{
          scope.row.Severity
        }}</el-tag>
      </template>
    </el-table-column>
    <el-table-column
      prop="Created"
      :label="$t('pagePostCodeLogs.table.Created')"
      sortable="custom"
      width="180"
      column-key="date"
    />
    <el-table-column
      prop="Message"
      :label="$t('pagePostCodeLogs.table.Message')"
      width="180"
    />
    <el-table-column
      prop="TimeStampOffset"
      :label="$t('pagePostCodeLogs.table.Oem.TimeStampOffset')"
    />
    <el-table-column label="Operations">
      <template #header>
        <search-box
          ref="search"
          :placeholder="$t('pageEventLogs.table.searchLogs')"
          data-test-id="eventLogs-input-searchLogs"
        />
      </template>
      <template #default="scope">
        <el-button
          class="bg-[var(--el-color-primary)]"
          type="primary"
          size="small"
          @click="handleExport(scope.$index, scope.row)"
          >{{ $t('global.action.export') }}</el-button
        >
      </template>
    </el-table-column>
  </el-table>

  <div class="demo-pagination-block mt-8">
    <el-pagination
      v-model:current-page="currentPage"
      v-model:page-size="perPage"
      :page-sizes="[10, 20, 30, 40]"
      :small="false"
      :disabled="false"
      :background="true"
      layout="sizes, prev, pager, next"
      :total="allLogs.length"
    />
  </div>
</template>

<script setup lang="ts">
import {
  usePostCodeLogStore,
  type Log,
} from '@/store/Diagnostic/PostCodeLog/PostCodeLogStore';
import _ from 'lodash';
import type { TableColumnCtx, TableInstance } from 'element-plus';
import useTableFilter from '@/hooks/useTableFilter';
import useDownload from '@/hooks/useDownload';
import { useI18n } from 'vue-i18n';

const postCodeLogStore = usePostCodeLogStore();
const { getFilteredTableDataByDate } = useTableFilter();
const { download } = useDownload();
const i18n = useI18n();

const search = ref();

postCodeLogStore.getPostCodesLogData();
const allLogs = computed(() => {
  filterLogs.value = _.cloneDeep(postCodeLogStore.allPostCodes);
  return _.cloneDeep(postCodeLogStore.allPostCodes);
});
const filterLogs = ref([] as Log[]);
const filterLogsComputed = computed(() => {
  filterLogs.value = filteredLogsByDate();
  if (search.value?.filter) {
    return filterLogs.value.filter((item) => {
      return _.includes(JSON.parse(JSON.stringify(item)), search.value.filter)
        ? true
        : false;
    });
  } else return filterLogs.value;
});

const TableData = computed(() => {
  const firstIndex = (currentPage.value - 1) * perPage.value;
  const lastIndex = currentPage.value * perPage.value;
  return filterLogsComputed.value.slice(firstIndex, lastIndex);
});

const sortChange = ({
  prop,
  order,
}: {
  column: { [index: string]: any };
  prop: string;
  order: null | 'descending' | 'ascending';
}) => {
  switch (order) {
    case 'descending':
      filterLogs.value.sort((a: any, b: any): any => {
        if (prop == 'date') {
          return b[prop].getTime() - a[prop].getTime();
        }
        return b[prop] - a[prop];
      });
      break;
    case 'ascending':
      filterLogs.value.sort((a: any, b: any): any => {
        if (prop == 'date') {
          return a[prop].getTime() - b[prop].getTime();
        }
        return a[prop] - b[prop];
      });
      break;
    default:
      filterLogs.value = _.cloneDeep(allLogs.value);
      break;
  }
};

const filteredLogsByDate = () => {
  return getFilteredTableDataByDate(
    _.cloneDeep(allLogs.value),
    filterStartDate.value as Date,
    filterEndDate.value as Date,
  );
};

const filterStartDate = ref(undefined as undefined | Date);
const filterEndDate = ref(undefined as undefined | Date);

const onChangeDateTimeFilter = ({
  fromDate,
  toDate,
}: {
  fromDate: ComputedRef<Date | undefined>;
  toDate: ComputedRef<Date | undefined>;
}) => {
  filterStartDate.value = fromDate.value;
  filterEndDate.value = toDate.value;
};

const perPage = ref(10);
const currentPage = ref(1);

const tableRef = ref<TableInstance>();

const multipleSelection = ref<Log[]>([]);

const tagType = (val: string) => {
  switch (val) {
    case 'OK':
      return 'success';
    case 'Critical':
      return 'danger';
    case 'Warning':
      return 'warning';
  }
};

const filterHandler = (
  value: string,
  row: Log,
  column: TableColumnCtx<Log>,
) => {
  const property = column['property'] as keyof Log;
  return row[property] === value;
};

const handleSelectionChange = (val: Log[]) => {
  multipleSelection.value = val;
};

const handleExport = (index: number, rowData: Log) => {
  download(
    exportFileNameByDate('export'),
    'data:text/json;charset=utf-8, ' + JSON.stringify(rowData),
  );
};

const BatchExportLogs = () => {
  download(
    exportFileNameByDate('export'),
    'data:text/json;charset=utf-8, ' + JSON.stringify(multipleSelection.value),
  );
};

const exportFileNameByDate = (value?: string) => {
  let date: Date | string = new Date();
  date =
    date.toISOString().slice(0, 10) +
    '_' +
    date.toString().split(':').join('-').split(' ')[4];
  let fileName;
  if (value === 'export') {
    fileName = 'event_log_';
  } else {
    fileName = 'all_event_logs_';
  }
  return fileName + date;
};

const exportAllLogs = () => {
  const info = postCodeLogStore.allPostCodes.map((Logs: any) => {
    const allPostCodesString = JSON.stringify(Logs);
    return allPostCodesString;
  });
  download(exportFileNameByDate(), 'data:text/json;charset=utf-8, ' + info);
};

const deleteAllLogs = (allLogs: any) => {
  ElMessageBox.confirm(
    i18n.t('pageEventLogs.modal.deleteAllMessage'),
    i18n.t('pageEventLogs.modal.deleteAllTitle'),
    {
      confirmButtonText: i18n.t('global.action.delete'),
      cancelButtonText: i18n.t('global.action.cancel'),
      type: 'warning',
    },
  )
    .then((confirm: any) => {
      if (confirm) {
        postCodeLogStore
          .deleteAll(allLogs.value)
          .then(() => {
            ElNotification({
              type: 'success',
              message: i18n.t('pageCodeLogs.toast.deleteSuccessfully'),
            });
          })
          .catch(() => {
            ElNotification({
              type: 'error',
              message: i18n.t('pageCodeLogs.toast.errorDelete'),
            });
          });
      }
    })
    .catch(() => {});
};
</script>
